home *** CD-ROM | disk | FTP | other *** search
- /*
- File: DrawShape.c
-
- Contains: QuickDraw GX to PostScript conversion code.
- File contains Main shape entry point for the Imaging Engine
-
- Version: Technology: Quickdraw GX 1.1.x
-
- Copyright: © 1991-1997 by Apple Computer, Inc., all rights reserved.
- */
-
- #include "GXToPSBuildConfig.h"
- #include <GXGraphics.h>
- #include "GXGraphicsPriv.h"
- #include <GXEnvironment.h>
- #include "GXToPostScript.h"
- #include "IOUtilities.h"
- #include "RDUtil.h"
- #include "FontHandler.h"
- #include "PublicPostScriptIE.h"
- #include "private.h"
- #include "PSIEResources.h"
- #include "GXErrors.h"
- #include "ProcessShape.h"
- #include "ShapeUtilities.h"
-
-
- #ifdef TIMEIE
- #include "timer.h"
- // 1 hour in milliseconds.
- #define maxShapeTime 60 * 60 * 1000
- #endif
-
- #ifdef resumeLabel
- #undef resumeLabel
- #endif
- #define resumeLabel(exception)
-
-
- //<FF>
- /**********************************************************
- Routine: ShapeToPostScript
-
- Routine controls the translation of a shape into PostScript.
- The shape must not be a picture or a QuickDraw Shape.
-
- context: A valid PostScript Imaging Engine context.
- theShape: the shape to translate.
- depth: The depth of the shape in the picture hierarchy.
- parents: An array of transforms which describe the ancestory of the shape, 1st is root.
-
-
- ************************************************************/
- OSErr ShapeToPostScript(TPSIEContext context, gxShape theShape, gxTransform *parents, long depth);
- OSErr ShapeToPostScript(TPSIEContext context, gxShape theShape, gxTransform *parents, long depth)
- {
- OSErr status = noErr;
- TIEGlobalsPtr pGlobals;
- long nSyn;
- TRDParams rdParams;
- TShapeStack shapeStack;
- gxShape aShape;
- Boolean shapeIsPSContinuation = false;
-
- #ifdef TIMEIE
- TMTask theTMTask;
- #endif
-
- #ifdef testapp
- gGlobalHdl = (TIEGlobalsHdl)context;
- #endif
-
- #ifdef lookAtShapeMapping
- {
- mapping theMapping;
- GetShapeMapping(theShape, &theMapping);
- dprintf(notrace, "Shape Coming in: %X, Its Mapping:\n%M", theShape, &theMapping);
- }
- #endif
-
- pGlobals = *(TIEGlobalsHdl)(context); // Dereference the context handle.
-
- #ifdef TIMEIE
- theTMTask.qLink = 0;
- theTMTask.qType = 0;
- theTMTask.tmAddr = 0;
- InsTime((QElemPtr)&theTMTask);
- PrimeTime((QElemPtr)&theTMTask, maxShapeTime);
- ++(pGlobals->shapeCount);
- #endif
-
-
- pGlobals->saveShape = theShape; // Save the shape.
-
- /** Check the shape for synonyms **/
-
- nSyn = GXGetShapeTags(theShape, gxPostScriptTag, 1, gxSelectToEnd, nil);
-
- /** Only bother to image if the shape has synonyms or isn't noFill **/
-
- if ( (GXGetShapeFill(theShape) != gxNoFill ) || (nSyn > 0) ) { // does shape draw anything?
-
- /*** Turn off text metric gridding so all text is in ideal space ***/
-
- GXSetShapeAttributes(theShape, GXGetShapeAttributes(theShape) | gxNoMetricsGridShape);
-
- /** If there are no synonyms, then make sure the shape is PostScriptable **/
-
- if (nSyn == 0) {
-
- /* The PS continue next flag shouldn't be set if the current shape doesn't have synonym */
-
- ncheck ( (*(TIEGlobalsHdl)context)->ieStateFlags & ePSContinueNext );
-
- /* We also ought not be getting pictures at this level */
-
- ncheck(TestShapeTypePict(theShape));
-
- /** First make the Transform heiarchy PostScriptable **/
-
- status = ResolveComplexTransform((TIEGlobalsHdl)context, parents, &depth, &theShape);
- nrequire(status, failed_ResolveComplexTransform);
-
- /** Second, Make the shape/style combination PostScriptable **/
-
- status = ValidateFillShape((TIEGlobalsHdl)context, &theShape);
- nrequire(status, failed_Validate);
-
- /** Third, Handle Large paths **/
-
- if (!TestShapeTypePict(theShape) || (nSyn > 0)) { // Could have a picture from Vallidate.
-
- nrequire(status = DissectShape((TIEGlobalsHdl)context, &theShape), failed_Split);
-
- } else { // Walk picture.
-
- nrequire(status = TMNewStack(&shapeStack), failed_NewStack);
- nrequire(status = TMPushShape(&shapeStack, theShape), failed_DrawShape);
-
- while (aShape = TMNextShape(&shapeStack)) {
-
- status = DissectShape((TIEGlobalsHdl)context, &aShape);
- nrequire(status, failed_Split);
-
- }//end while
-
- TMDisposeStack(&shapeStack);
-
- }//end if
-
- } else {
-
- /* Shape has a postscript synonym, see if it is a continuation of the last shape */
-
- pGlobals = *(TIEGlobalsHdl)(context); // Dereference the context handle.
-
- shapeIsPSContinuation = (pGlobals->ieStateFlags & ePSContinueNext) ? true : false;
-
- }//end if
-
-
- pGlobals = *(TIEGlobalsHdl)(context); // Dereference the context handle.
-
- pGlobals->pRDParams = &rdParams; // pointer to the param block on stack.
-
- /**************
- Set up the res dump utility parameter block for usual case
- all lower level drones expect everything set here to be
- maintained. If any drones change these fields, they must
- restore them before calling on to other drones or returning!!
- ***************/
-
- rdParams.rdMap = pGlobals->rdMap;
- rdParams.resType = kScriptResType;
- rdParams.resID = kScriptResID;
- rdParams.rdFlags = eRDCharSubs + eRDNoAutoFlush;
-
- status = pGlobals->psDevice->Idle(); // DL 7/8/97
- //nrequire(status = GXJobIdle(), failed_Idle); // Idle at least once per shape.
-
- if (!TestShapeTypePict(theShape) || (nSyn > 0)) { // Could have a picture from PostScriptablizing the shape.
-
- /** If it is continuation postscript, just bypass the shape drone, call synonym drone - otherwise process it as normal shape **/
-
- if (shapeIsPSContinuation)
- nrequire(status = PostScriptSynonymDrone((TIEGlobalsHdl)context, theShape, nSyn), failed_Draw);
- else
- nrequire(status = ShapeDrone((TIEGlobalsHdl)context, theShape, parents, depth), failed_Draw);
-
- } else { // Walk picture and translate each shape.
-
- nrequire(status = TMNewStack(&shapeStack), failed_NewStack);
- nrequire(status = TMPushShape(&shapeStack, theShape), failed_DrawShape);
-
- while (aShape = TMNextShape(&shapeStack)) {
-
- status = ShapeDrone((TIEGlobalsHdl)context, aShape, parents, depth);
- nrequire(status, failed_DrawShape);
-
- }//end while
-
- failed_DrawShape:
- TMDisposeStack(&shapeStack);
-
- }//end if
-
- failed_NewStack:
- failed_Draw:
- failed_Idle:
-
- pGlobals = *(TIEGlobalsHdl)(context); // Dereference the context handle.
-
- /** Check to see if the shape changed, if it did dispose of the new one. **/
-
- if (pGlobals->saveShape != theShape)
- GXDisposeShape(theShape);
-
- }//end if (does shape draw anything?)
-
- failed_Split:
- failed_Validate:
- failed_ResolveComplexTransform:
-
- if (status == noErr)
- status = GXGetGraphicsError(nil);
-
- #ifdef TIMEIE
- RmvTime((QElemPtr)&theTMTask);
- pGlobals->shapeTime += maxShapeTime - theTMTask.tmCount;
- #endif
-
- return(status);
-
- }//ShapeToPostScript
-
-
-
- //<FF>
-
- /*-----------------------------------------------------------------------*/
-
- /** Structure for translator refcon for QD Pict Shapes **/
-
- typedef struct {
-
- OSErr status;
- TPSIEContext context; // Imaging Engine context.
- gxTransform *parents; // parent transform list.
- long depth; // transform list depth.
-
- } TIEqdTranslation;
-
- /*********************************************
-
- Callback for imaging QuickDraw Pict shapes.
-
- **********************************************/
- gxGraphicsError PSTranslationCallBack(gxShape theShape, long refCon);
- gxGraphicsError PSTranslationCallBack(gxShape theShape, long refCon)
- {
- TIEqdTranslation *qdTranslation = (TIEqdTranslation*)refCon;
-
- qdTranslation->status = ShapeToPostScript(qdTranslation->context, theShape, qdTranslation->parents, qdTranslation->depth);
- ncheck(qdTranslation->status);
-
- if (qdTranslation->status != noErr)
- return(1); // just non-zero value
- else
- return(0);
-
- }//TranslationCallBack
-
-
- //<FF>
- #if DEBUGLEVEL > 2
- // #define DRAWSHAPESONSCREEN
- #endif
-
- #ifdef DRAWSHAPESONSCREEN
- void DEBUGDrawShapeOnScreen(gxShape theShape, gxTransform *parents, long depth)
- {
- long i;
- gxShape thePicture[26];
-
- check(depth <= 25);
-
- /** Build a picture heirarchy to reflect the parents **/
-
- thePicture[0] = GXNewShape(gxPictureType); // Create a root level picture.
-
- for (i = 0; i < depth; ++i) {
-
- thePicture[i+1] = GXNewShape(gxPictureType);
- GXSetShapeTransform(thePicture[i+1], parents[i]);
-
- GXSetPictureParts(thePicture[i], 1, 0, 1, &(thePicture[i+1]), nil, nil, nil);
-
- }//end of
-
- /* Add the shape to the heirarchy */
-
- GXSetPictureParts(thePicture[depth], 1, 0, 1, &theShape, nil, nil, nil);
-
- GXDrawShape(thePicture[0]);
-
- for (i = 0; i <= depth; ++i) {
-
- GXDisposeShape(thePicture[i]);
-
- }//end of
-
- }//DEBUGDrawShapeOnScreen
-
- #endif
-
-
- /**********************************************************
- Routine: PostScriptDrawShape
-
- Routine controls the translation of a shape into PostScript.
- This is the root level call for a GX shape. Routine will
- handle the translation of QuickDraw shapes.
-
- context: A valid PostScript Imaging Engine context.
- theShape: the shape to translate.
- depth: The depth of the shape in the picture hierarchy.
- parents: An array of transforms which describe the ancestory of the shape, 1st is root.
-
-
- ************************************************************/
- OSErr PostScriptDrawShape(TPSIEContext context, gxShape theShape, gxTransform *parents, long depth)
- {
- OSErr status;
- gxShapeType theType;
-
- #ifdef DRAWSHAPESONSCREEN
- DEBUGDrawShapeOnScreen(theShape, parents, depth);
- //return(noErr);
- #endif
-
- theType = QGXGetShapeType(theShape);
-
- if (theType != gxQuickDrawPictType) {
-
- status = ShapeToPostScript(context, theShape, parents, depth);
- nrequire(status, failed_shape);
-
- } else {
-
- TIEqdTranslation qdTranslation;
- gxTranslationStatistic stats;
- gxTransform theTransform = GXGetShapeTransform(theShape);
- gxMapping aMapping;
- gxTransform *newParents = nil;
-
- #if GENERATINGPOWERPC
- RoutineDescriptor callBackDesc = BUILD_ROUTINE_DESCRIPTOR(uppgxShapeSpoolProcInfo, PSTranslationCallBack);
- gxShapeSpoolUPP uppPSTranslationCallBack = (gxShapeSpoolUPP) &callBackDesc;
- #else
- gxShapeSpoolUPP uppPSTranslationCallBack = (gxShapeSpoolUPP) PSTranslationCallBack;
- #endif
-
- qdTranslation.context = context;
-
- /**************
-
- Invoke translation of QuickDraw PICT shape and image one at a time.
-
- Our Translation refcon will be a pointer to a structure containing parameters
- necessary to pass to ShapeToPostScript.
-
- If the transform of the QuickDraw shape is identity then we can just pass the original
- transform list through. If it is not, we must add it to the transform list so that
- shapes generated by the translator will draw through the QD shape's transform
- as well as the ones that are in the transform list.
-
- ***************/
-
- if ( TestMappingIdentity(GXGetTransformMapping(theTransform, &aMapping) ) &&
- (GetTransformClipType(theTransform) == gxFullType) ) {
-
- qdTranslation.parents = parents;
- qdTranslation.depth = depth;
-
- } else {
-
- /* Make new parent transform list, 1 bigger to hold QD shape's transform */
-
- status = PrNewPtr((Ptr*)&newParents, (depth + 1) * sizeof(gxTransform));
- nrequire(status, failed_newPtr);
-
- BlockMove((Ptr)parents, (Ptr)newParents, depth * sizeof(gxTransform));
- newParents[depth] = theTransform;
- qdTranslation.parents = newParents;
- qdTranslation.depth = depth + 1;
-
- }//end if
-
- qdTranslation.status = noErr;
- status = QGXTranslateQuickDrawPict(theShape, uppPSTranslationCallBack, (long)&qdTranslation, &stats);
- if (status == noErr)
- status = qdTranslation.status;
-
- if (newParents != nil)
- DisposePtr((Ptr)newParents);
- }//end if
-
- /** Flush the RDUtilities Buffer per shape in case extension is using BufferData **/
-
- status = RDFlushBuffer((*(TIEGlobalsHdl)context)->rdMap);
- ncheck(status);
-
- failed_newPtr:
- failed_shape:
-
- return(status);
-
- }//PostScriptDrawShape
-
-
-
-
-
-